(function(wnd) {
	"use strict";
	var doc = wnd.document;

	var actionURL = "testxml.do"

	var handler = null;

	var reg = /{(?:\w+\.\w+)}/g;
	//var reg= /{\w+\.\w+}/g
	var dataquerypreg = /({\w+})/g;

	var editor = null;

	TagHandler.ignore = "ignore";// 有这个忽略解析
	
	var foldericon = "../code/test/folder.gif";
	
	var xmlicon = "../code/test/xml.gif";

	function TagHandler() {

	}

	function getTextContent4Xml(xmlNode){
		return xmlNode.textContent;
	}

	var handler_request = {
		"regData" : function(){

		},
		"unregData":function(){

		},
		"getData" : function(param){
			var dataSrc = wnd.__dataSrc;
			var args = param.args;
			var callback = param.callback;
			var mres = args[0];
			var tagData = [];
			for(var i= 0,len = mres.length;i<len;i++){
					var mre = mres[i];
					mre = mre.substring(1,mre.length-1);
					var dataStr = mre.split(".");
					var length = dataStr.length;
					var curData = getObjData(dataStr,dataSrc,1);
					tagData.push(curData);
			}
			args.splice(0,0,tagData);
			callback.apply(null,args);
		}
	}

	function getObjData(dataStr,dataSrc,index){
		var data = dataSrc[dataStr[index]];
		if(data){
			if(++index == dataStr.length ){
				return data;
			}else{
				return getObjData(dataStr,data,index);
			}
		}else{
			return "";
		}
	}



	TagHandler.prototype.handler = function(dom, xmlNode, tagData, donotCheckData) {// 解析handler
		var temp = xmlNode, hasChild = false;
		var tagName = xmlNode.tagName;
		if (xmlNode.nodeType == 3) {
			var text = getTextContent4Xml(xmlNode);
			var textNode = dom.appendChild(doc.createTextNode(text));
			var mres = null;
			if (!donotCheckData) {
				mres = checkHasData(text)
			}
			if (mres) {
				var len = mres.length;
				for ( var i = 0; i < len; i++) {
					var res = mres[i];
					res = res.substring(1, res.length - 1);
					var data = tagData[i];
					if (data) {
						textNode.textContent = textNode.textContent.replace(mres[i], data);
					} else {
						var text = textNode.textContent;
						textNode.textContent = textNode.textContent.replace(mres[i], "");
						textNode.lastContent = text;
						pushCallBack({
							callback : transData4TextNode,
							args : [ mres, textNode ,dom]
						});
					}
				}
			}
			return dom;
		}
		if (xmlNode.nodeType != 1) return;
		var data_query = xmlNode.getAttribute("data-query");
		if (data_query) {
			var datares = data_query.match(dataquerypreg);
			if (datares) {
				for ( var dnum = 0, dlen = datares.length; dnum < dlen; dnum++) {
					var dres = datares[dnum], key = dres.substring(1, dres.length - 1);
					var data = tagData[key] || "";
					data_query = data_query.replace(dres, data)
				}
//				xmlNode.setAttribute("data-query", data_query);
			}
		}
		handler_request["regData"](data_query);
		var handler = handlers[tagName];
		if (handler) {
			handler.call(this,dom, xmlNode, tagData, donotCheckData)
		} else {
			var selfdom = doc.createElement(tagName);
			dom.appendChild(selfdom);
			addProp(selfdom, xmlNode, tagData, donotCheckData);
			var childs = xmlNode.childNodes;
			for ( var i = 0, len = childs.length; i < len; i++) {
				var child = childs[i];
				this.handler(selfdom, child, tagData, donotCheckData);
			}
		}
		handler_request["unregData"](data_query);
		return dom;
	}

	/**
	 * 每个标签的解析
	 */
	var handlers = {
		show : function(dom, xmlNode, tagData, donotCheckData) {
			var div = doc.createElement("div");
			dom.appendChild(div);
			div.className = "tag_show";
			var childs = xmlNode.childNodes;
			for ( var i = 0, len = childs.length; i < len; i++) {
				handler.handler(div, childs[i], tagData, donotCheckData);
			}
			addProp(div, xmlNode, tagData, donotCheckData);
			return div;
		},
		grid : function(dom, xmlNode, tagData, donotCheckData) {

		},
		text : function(dom, xmlNode, tagData, donotCheckData) {
			var text = doc.createElement("span");
			dom.appendChild(text);
			var childs = xmlNode.childNodes;
			var noCheckData = xmlNode.getAttribute("noData");
			if (noCheckData == "true") donotCheckData = true;
			for ( var i = 0, len = childs.length; i < len; i++) {
				var child = childs[i];
				handler.handler(text, child, tagData, donotCheckData);
			}
			addProp(text, xmlNode, tagData, donotCheckData);
			return text;
		},
		link : function(dom, xmlNode, tagData, donotCheckData) {
			var span = doc.createElement("span");
			$(span).addClass("kendo_link");
			var location = xmlNode.getAttribute("location");
			span.setAttribute("location", location);
			var param = xmlNode.getAttribute("param");
			span.setAttribute("param", param);
			dom.appendChild(span);
			var childs = xmlNode.childNodes;
			for ( var i = 0, len = childs.length; i < len; i++) {
				var child = childs[i];
				handler.handler(span, child, tagData, donotCheckData);
			}
			span.onclick = link_click_evt;
			addProp(span, xmlNode, tagData, donotCheckData);
			return span;
		},
		tab : function(dom, xmlNode, tagData, donotCheckData) {

		},
		container : function(dom, xmlNode, tagData, donotCheckData) {
			var fieldset = doc.createElement("fieldset");
			fieldset.className = "tag_container";
			dom.appendChild(fieldset);
			var title = xmlNode.getAttribute("caption");
			if (title) {
				var legend = doc.createElement("legend");
				var tmres = checkHasData(title);
				fieldset.appendChild(legend);
				if (tmres) {
					var orititle = title;
					title = transText(title, tmres, tagData);
					pushCallBack({
						callback : transData4ContainerTitle,
						args : [ tmres, orititle, legend ]
					});
				}else{
					legend.textContent = title;
				}
			} else {
				fieldset.style.border = "0px";
			}
			var layout = xmlNode.getAttribute("layout");
			if (layout) {
				if (layout.indexOf("table") != -1) {
					var tableLayout = layout.split(":");
					var col = 3, row = 3;
					if (tableLayout[1]) {
						var colAndRow = tableLayout[1].split("*");
						row = parseInt(colAndRow[0]), col = parseInt(parseInt(colAndRow[1]));
					}
					tableLayout[2] = tableLayout[2] || "50";
					tableLayout[3] = tableLayout[3] || "20";
					var child = xmlNode.firstChild;

					var table = doc.createElement("table");
					table.className = "table_container";
					var tablestyle = xmlNode.getAttribute("tablestyle");
					table.style.cssText += ";" + tablestyle || "";
					fieldset.appendChild(table);
					for ( var r = 0; r < row; r++) {
						var newRow = fieldset[r + "row"] = table.insertRow(-1);
						newRow.style.cssText += ";height:" + tableLayout[2] + "px;";
						for ( var c = 0; c < col; c++) {
							var cell = fieldset[r + "_" + c + "cell"] = newRow.insertCell(-1);
							while (child && child.nodeType != 1)
								child = child.nextSibling;
							if (child) {
								cell.style.cssText += ";padding-left:" + tableLayout[3] + "px;";
								this.handler(cell, child, tagData);//
								child = child.nextSibling;
							}
						}
					}
					while (child) {
						if (child) {
							this.handler(fieldset, child, tagData, donotCheckData);
						}
						child = child.nextSibling;// 剩下的继续解析
					}
				}
			} else {
				handler.handler(fieldset, xmlNode, tagData, donotCheckData);
			}
			addProp(fieldset, xmlNode, tagData, donotCheckData);
			return fieldset;
		},
		spliter : function(dom, xmlNode, tagData, donotCheckData) {

		},
		tree : function(dom, xmlNode, tagData, donotCheckData) {

		},
		contextMenu : function(dom, xmlNode, tagData, donotCheckData) {
			var evtSrc = xmlNode.getAttribute("eventSource");
			if (!wnd[evtSrc]) evtSrc = events;
			var itemHandler = function(menu, xmlNode) {
				var childs = xmlNode.childNodes;
				for ( var i = 0, len = childs.length; i < len; i++) {
					var child = childs[i];
					if (child.nodeType != 1) continue;
					var text = child.getAttribute("text") || "菜单项";
					var icon = child.getAttribute("icon");
					var evt = child.getAttribute("event");
					var type = child.getAttribute("type");
					if ("--" == text) {
						menu.addHr();
					} else {
						var newMenu = menu.addXMenuItem(text, icon, events[evt]);
						newMenu.type = type;
						itemHandler(newMenu, child)
					}
				}
			}
			var menu = new XPopupMenu(wnd);
			itemHandler(menu, xmlNode);
			if (dom._obj) {
				return menu;
			} else {
				dom.oncontextmenu = function() {
					menu.popupAtCursor();
					return false;
				}
			}
		},
		page : function(dom, xmlNode, tagData, donotCheckData) {
			var page = doc.createElement("div");
			dom.appendChild(page);
			var caption = xmlNode.getAttribute("caption");
			if (caption) {
				var oricaption = caption;
				var cmres = checkHasData(caption);
				if (cmres) {
					caption = transText(caption, cmres, tagData);
					pushCallBack({
						callback : transData4PageTitle,
						args : [ cmres, oricaption, doc ]
					});
				}
				doc.title = caption;
			}
			var childs = xmlNode.childNodes;
			for ( var i = 0, len = childs.length; i < len; i++) {
				var child = childs[i];
				handler.handler(page, child, tagData);
			}
			addProp(page, xmlNode, tagData, donotCheckData);
		},
		chart : function(dom, xmlNode, tagData) {

		},
		box : function(dom, xmlNode, tagData, donotCheckData) {
			var box = dom.appendChild(doc.createElement("div"));
			var childs = xmlNode.childNodes;
			for ( var i = 0, len = childs.length; i < len; i++) {
				handler.handler(box, childs[i], tagData, donotCheckData);
			}
			addProp(box, xmlNode, tagData, donotCheckData)
		},
		digraph : function(dom, xmlNode, tagData) {
			var json = getTextContent4Xml(xmlNode);
			var canvas = dom.appendChild(doc.createElement("canvas"));
			canvas.className = "tag_canvas";
			var data = xmlNode.getAttribute("data");
			if (data) {
				var graph = digraph_data[data](xmlNode);
				var springy = jQuery(canvas).springy({
					graph : graph
				});
			}
			addProp(canvas, xmlNode, tagData);
		},
		listView : function(dom,xmlNode,tagData,noCheckData){

		},
		treeList : function(dom,xmlNode,tagData,noCheckData){

		},
		input : function(dom,xmlNode,tagData,noCheckData){
			var input = dom.appendChild(doc.createElement("input"));
			var editable = xmlNode.getAttribute("editable");
			if(editable == "true"){

			}
			input.onchange = function(){

			}
			addProp(input, xmlNode, tagData, noCheckData)
		}
	}

	var events = {
		refresh : function() {
			location.reload();
		},
		stop : function(){
			bullet_timer = false;
		},
		addGroup : function(item) {
			var xtree = item.owner.treeItem;
			var str = prompt("请输入分组名", "新分组");
			var parentId = xtree.id;
			if (xtree instanceof XTree) parentId = "--";
			var map = new Map();
			map.put("action", "new");
			map.put("parentId", parentId);
			map.put("type", "unleaf");
			map.put("text", str);
			new QueryObj("resourceTree.do", map, function(res) {
				var res = res.getResponseJSON();
				var id = res.id;
				var item = null;
				if (xtree instanceof XTree) {
					item = xtree.rootItem.appendChild(str);
					item.type = "unleaf";
				} else {
					item = xtree.appendChild(str);
					item.type = "unleaf";
				}
				item.setItemImage(foldericon);
				item.id = id;

			});
		},
		addItem : function(item) {
			var treeitem = item.owner.treeItem;
			if (!editor) editor = initEditor(doc, editor_ok);
			editor.setValue({
				xml : "<page>\n</page>"
			});
			editor.setVisible(true);
			editor.options = {
				action : "add",
				target : treeitem
			};
		},
		editItem : function(item) {
			var treeitem = item.owner.treeItem;
			if (!treeitem || treeitem.hasChildren()) return;
			var url = "esmain/" + actionURL + "?" + "action=xmlPath&" + treeitem.url;
			new QueryObj(url, new Map(), function(data) {
				if (!editor) editor = initEditor(doc, editor_ok);
				editor.options = {
					action : "edit",
					target : treeitem
				};
				var filename = treeitem.url.lastIndexOf("/");
				filename = treeitem.url.substring(filename + 1);
				var text = data.getResponseText();
				editor.setVisible(true);
				editor.setValue({
					xml : text,
					nodeName : treeitem.itemText,
					fileName : filename
				});
			});
		}

	};

	var commonProp = {
		position : ""
	}

	function addProp(dom, xmlNode, tagData, donotCheckData) {
		if (!tagData) tagData = {};
		var attributes = xmlNode.attributes;
		for ( var m = 0, mlen = attributes.length; m < mlen; m++) {
			var attr = attributes[m];
			var name = attr.name, value = getTextContent4Xml(attr);
			var newAttrNode = doc.createAttribute(name);
			dom.setAttributeNode(newAttrNode);
			var mres = null;
			if (!donotCheckData) mres = value.match(reg);
			if (mres && mres.length) {
				var len = mres.length;
				for ( var i = 0; i < len; i++) {
					var res = mres[i];
					res = res.substring(1, res.length - 1);
					var data = tagData[res.toUpperCase()];
					if (data) {
						newAttrNode.textContent = value.replace(mres[i], data);
					} else {
						newAttrNode.lastContent = newAttrNode.textContent = value;
						newAttrNode.textContent = newAttrNode.lastContent.replace(mres[i], "");
						pushCallBack({
							callback : transData4TextNode,
							args : [ mres, newAttrNode ,dom]
						});
					}
				}
			} else {
				newAttrNode.textContent = value;
			}
		}
	}
	;

	function isArray(arr){
		return $.isArray(arr);
	}

	var transData4TextNode = function(tagData, mres, node,parentNode) {// 文本节点回调方法
		if (isArray(tagData[0])) return;// 说明是多条数据 返回
		var len = mres.length;
		if(parentNode){
		}
		for ( var i = 0; i < len; i++) {
			var res = mres[i];
			res = res.substring(1, res.length - 1);
			var data = tagData[i];
			node.textContent = node.lastContent.replace(mres[i], data);
			node.lastContent = node.textContent;
		}
	};

	var transData4ContainerTitle = function(tagData, tmres, orititle, legend) {
		orititle = transText(orititle, tmres, tagData);
		legend.textContent = orititle;
	}
	
	var transData4PageTitle = function(tagData, cmres, oricaption, doc) {
		oricaption = transText(oricaption, cmres, tagData);
		doc.title = oricaption;
		if (wnd.__esen_bi_workspace) {
			wnd.__esen_bi_workspace.reloadTitleBar(wnd);
		}
	}



	/**
	 * 
	 */
	function transText(text, mres, tagData) {
		if (mres && mres.length) {
			var len = mres.length;
			for ( var i = 0; i < len; i++) {
				var res = mres[i];
				res = res.substring(1, res.length - 1);
				var data = tagData[i];
				if (isArray(data)) data = "";
				text = text.replace(mres[i], data || "");
			}
			return text;
		}
		return text;
	}
	function link_click_evt() {// 连接点击事件
		var location = this.getAttribute("location");
		var param = this.getAttribute("param");
		if (param) param = "&" + param;
		wnd.__esen_bi_workspace.showFrame(param, location + param, null, this.getAttribute("title") || "正在加载...");
		return false;
	}

	function start() {
		handler = new TagHandler();
		//var handlerxml = doc.getElementById("handler_xml");
		//if (handlerxml.value) {
		//	parseXML(handlerxml.value, function(xmlNode) {
		//		var tagNode = xmlNode.getElementsByTagName("tag");
		//		if (tagNode) {
		//			tagNode = tagNode[0];
		//			var handlerJson = getCDATASectionValue(tagNode);
		//		}
		//		var eventNode = xmlNode.getElementsByTagName("event");
		//		if (eventNode) {
		//			eventNode = eventNode[0];
		//			var eventJson = getCDATASectionValue(eventNode);
		//		}
		//		try {
		//			var handlerObj = eval("(" + handlerJson + ")");
		//			var eventObj = eval("(" + eventJson + ")");
		//			for ( var m in handlerObj) {
		//				handlers[m] = handlerObj[m];
		//			}
		//			for ( var evt in eventJson) {
		//				window[evt] = eventJson[evt];
		//			}
		//		} catch (error) {
		//			console.log("handler配置文件出错")
		//		}
        //
		//	});
		//}
		//var xml = doc.getElementById("hidden_xml");
		//if (!xml.value) return;
		xml.value = xml.value.replaceAll("&", "&amp;");//转义
		var xmlNode = parseXML(xml.value, function(xmlNode) {
			while (xmlNode.nodeType != 1) {
				xmlNode = xmlNode.nextSibling;
			}
			var tagData = {};
			//var params = wnd.location.search;
			//if (params) {
			//	params = decodeURI(params)
			//	params = params.substring(1);
			//	params = params.trim().split("&");
			//	for ( var l = 0, llen = params.length; l < llen; l++) {
			//		var param = params[l].split("=");
			//		var key = param[0], value = param[1];
			//		tagData[key] = value;
			//	}
			//}
			handler.handler(doc.body, xmlNode, tagData);
		});
	}

	function checkHasData(text) {// 检查是否有数据节点
		if (!text || !text.match) return false;
		var mres = text.match(reg);
		if (mres && mres.length) {
			return mres;
		}
		return false;
	}
	function pushCallBack(callobj) {
		handler_request["getData"](callobj);
	}

	function firstToUpperCase(str) {
		if (typeof str != "string") return;
		str = str.charAt(0).toUpperCase() + str.substring(1);
		return str;
	}

	function editor_ok(values) {
		if (!editor) return;
		var option = editor.options;
		var target = option["target"];
		var action = option["action"];
		var nodeName = values["nodeName"] || "新节点";
		var fileName = values["fileName"] || "";
		var xml = values["xml"];
		switch (action) {
			case "add":
				treeEvent.addItem(target, nodeName, xml, fileName);
				break;
			case "edit":
				treeEvent.editItem(target, nodeName, xml, fileName);
				break;
		}
		editor.setVisible(false);
	}

	var treeEvent = {
		addItem : function(parent, text, xml, fileName) {
			var pid = parent.id;
			var map = new Map();
			map.put("parentId", pid);
			map.put("text", text);
			map.put("xml", xml);
			map.put("type", "leaf")
			map.put("action", "new");
			map.put("fileName", fileName);
			new QueryObj("resourceTree.do", map, function(res) {
				var data = res.getResponseJSON();
				var item = parent.appendChild(text);
				item.id = data.id;
				item.url = data.url;
				item.type = "leaf";
				item.setItemImage(xmlicon);
			});
		},
		editItem : function(treeItem, text, xml, fileName) {
			var map = new Map();
			var id = treeItem.id;
			map.put("id", id);
			map.put("text", text);
			map.put("xml", xml);
			map.put("type", treeItem.type)
			map.put("url", treeItem.url);
			map.put("action", "editNode");
			map.put("fileName", fileName);
			new QueryObj("testxml.do", map, function(res) {
				var data = res.getResponseJSON();
				if (data.status == "ok") {
					treeItem.setItemText(text);
					treeItem.url = data.url;
				}
			});
		}
	}

	//wnd["handler_start"] = start;
	//start();
	wnd["TagHandler"] = TagHandler;
})(window)
